﻿using System;
using System.Collections;
using System.Data;
using System.IO;
using System.Net;
using System.Runtime.CompilerServices;
using System.Text;
using System.Xml;
using Windows32;

namespace ZYCommon
{
    

    public class XMLHttpConnection : IDbConnection, IDisposable
    {
        private bool bolWinInetAPI;
        public XMLHttpDBExecutingHandler ExecuteEvent;
        private int intConnectionTimeout;
        private int intRetryNum;
        private ConnectionState intState;
        private XMLHttpConnectionString myConnectionString;
        private WinInet myInet;
        private Encoding myReserveEncod;
        private Encoding mySendEncod;
        private Cookie mySessionCookie;
        private string strDataBase;
        private string strHttpMethod;
        private string strIECookies;

        public event EventHandler OnCancelPostData;

        public XMLHttpConnection()
        {
            this.myConnectionString = new XMLHttpConnectionString();
            this.intState = ConnectionState.Closed;
            this.strDataBase = null;
            this.intConnectionTimeout = 0;
            this.strIECookies = null;
            this.bolWinInetAPI = true;
            this.intRetryNum = 3;
            this.OnCancelPostData = null;
            this.mySendEncod = null;
            this.myReserveEncod = null;
            this.mySessionCookie = null;
            this.ExecuteEvent = null;
            this.strHttpMethod = "POST";
            this.myInet = new WinInet();
        }

        public XMLHttpConnection(XMLHttpConnectionString vConn)
        {
            this.myConnectionString = new XMLHttpConnectionString();
            this.intState = ConnectionState.Closed;
            this.strDataBase = null;
            this.intConnectionTimeout = 0;
            this.strIECookies = null;
            this.bolWinInetAPI = true;
            this.intRetryNum = 3;
            this.OnCancelPostData = null;
            this.mySendEncod = null;
            this.myReserveEncod = null;
            this.mySessionCookie = null;
            this.ExecuteEvent = null;
            this.strHttpMethod = "POST";
            this.myInet = new WinInet();
            this.myConnectionString = vConn;
        }

        public XMLHttpConnection(string strConn)
        {
            this.myConnectionString = new XMLHttpConnectionString();
            this.intState = ConnectionState.Closed;
            this.strDataBase = null;
            this.intConnectionTimeout = 0;
            this.strIECookies = null;
            this.bolWinInetAPI = true;
            this.intRetryNum = 3;
            this.OnCancelPostData = null;
            this.mySendEncod = null;
            this.myReserveEncod = null;
            this.mySessionCookie = null;
            this.ExecuteEvent = null;
            this.strHttpMethod = "POST";
            this.myInet = new WinInet();
            this.ConnectionString = strConn;
        }

        public IDbTransaction BeginTransaction(IsolationLevel il)
        {
            return null;
        }

        public void CancelPostData()
        {
            if (this.OnCancelPostData != null)
            {
                this.OnCancelPostData(this, null);
            }
        }

        public void ChangeDatabase(string databaseName)
        {
            this.strDataBase = databaseName;
        }

        public void Close()
        {
            if (this.bolWinInetAPI)
            {
                this.myInet.Close();
            }
        }

        public IDbCommand CreateCommand()
        {
            XMLHttpCommand command = new XMLHttpCommand();
            command.Connection = this;
            command.ExecuteEvent = this.ExecuteEvent;
            command.HttpMethod = this.HttpMethod;
            return command;
        }

        internal HttpWebRequest CreateHttpRequest()
        {
            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(this.myConnectionString.ServerPageURL);
            if (this.mySessionCookie != null)
            {
                request.CookieContainer = new CookieContainer();
                request.CookieContainer.Add(this.mySessionCookie);
            }
            request.ContentType = "application/x-www-form-urlencoded";
            request.Method = this.strHttpMethod;
            return request;
        }

        public void Dispose()
        {
            this.myInet.Close();
        }

        public static ArrayList GetHttpPostEncoding(HttpPostDataHandler vPostData)
        {
            ArrayList list = new ArrayList();
            list.Add(Encoding.GetEncoding(0x3a8));
            list.Add(Encoding.UTF8);
            list.Add(Encoding.Unicode);
            list.Add(Encoding.UTF7);
            list.Add(Encoding.ASCII);
            XmlDocument document = new XmlDocument();
            document.LoadXml("<xmlhttpconnection />");
            document.DocumentElement.SetAttribute("text", "[testconnection]");
            document.DocumentElement.SetAttribute("data", "test_ok_中文测试");
            string outerXml = document.DocumentElement.OuterXml;
            for (int i = 0; i < list.Count; i++)
            {
                byte[] bytes = (list[i] as Encoding).GetBytes(outerXml);
                byte[] buffer2 = vPostData(bytes);
                if (buffer2 == null)
                {
                    return null;
                }
                for (int j = 0; j < list.Count; j++)
                {
                    Encoding encoding = (Encoding) list[j];
                    string str2 = new string(encoding.GetChars(buffer2));
                    if (str2.IndexOf("test_ok_中文测试") >= 0)
                    {
                        ArrayList list2 = new ArrayList();
                        list2.Add(list[i]);
                        list2.Add(list[j]);
                        return list2;
                    }
                }
            }
            return null;
        }

        private byte[] InnerPostData(byte[] bytSend)
        {
            return this.PostData(bytSend, null);
        }

        public void Open()
        {
            this.intState = ConnectionState.Connecting;
            if (this.bolWinInetAPI)
            {
                this.myInet.Open(this.myConnectionString.ServerPageURL);
                this.myInet.Heads.Clear();
                this.myInet.Heads.Set("Content-Type", "application/x-www-form-urlencoded");
                this.myInet.Heads.Set("Host", this.myInet.Uri.Host);
                this.myInet.Heads.Set("Accept", "*/*");
                string[] strArray = StringCommon.AnalyseStringList(this.strIECookies, ';', '=', false);
                if (strArray != null)
                {
                    for (int i = 0; i < strArray.Length; i += 2)
                    {
                        this.myInet.SetCookie(strArray[i], strArray[i + 1]);
                    }
                }
            }
            ArrayList httpPostEncoding = GetHttpPostEncoding(new HttpPostDataHandler(this.InnerPostData));
            if (httpPostEncoding == null)
            {
                this.intState = ConnectionState.Closed;
                throw new Exception("无法打开数据库，服务器不存在或未能找到正确的编码格式");
            }
            this.mySendEncod = (Encoding) httpPostEncoding[0];
            this.myReserveEncod = (Encoding) httpPostEncoding[1];
            this.intState = ConnectionState.Open;
        }

        public byte[] PostData(byte[] bytSend, XMLHttpCommand cmd)
        {
            for (int i = 0; i < this.RetryNum; i++)
            {
                if ((cmd != null) && cmd.bolCancel)
                {
                    return null;
                }
                if (this.bolWinInetAPI)
                {
                    byte[] buffer = null;
                    if (cmd != null)
                    {
                        buffer = this.myInet.PostData(bytSend, ref cmd.bolCancel);
                    }
                    else
                    {
                        buffer = this.myInet.PostData(bytSend);
                    }
                    if (buffer != null)
                    {
                        return buffer;
                    }
                    continue;
                }
                HttpWebRequest request = this.CreateHttpRequest();
                if (this.mySessionCookie == null)
                {
                    request.CookieContainer = new CookieContainer();
                }
                Stream requestStream = request.GetRequestStream();
                int offset = 0;
                while ((offset < bytSend.Length) && ((cmd == null) || !cmd.bolCancel))
                {
                    if ((offset + 0x400) > bytSend.Length)
                    {
                        requestStream.Write(bytSend, offset, bytSend.Length - offset);
                        offset = bytSend.Length;
                    }
                    else
                    {
                        requestStream.Write(bytSend, offset, 0x400);
                        offset += 0x400;
                    }
                }
                requestStream.Close();
                if ((cmd == null) || !cmd.bolCancel)
                {
                    request.Abort();
                    return null;
                }
                HttpWebResponse response = null;
                response = request.GetResponse() as HttpWebResponse;
                if (this.mySessionCookie == null)
                {
                    foreach (Cookie cookie in response.Cookies)
                    {
                        if (cookie.Name.ToUpper().IndexOf("SESSION") >= 0)
                        {
                            this.mySessionCookie = cookie;
                            string[] strArray = StringCommon.AnalyseStringList(this.strIECookies, ';', '=', false);
                            if (strArray != null)
                            {
                                for (int j = 0; j < strArray.Length; j += 2)
                                {
                                    if (this.mySessionCookie.Name == strArray[j])
                                    {
                                        this.mySessionCookie.Value = strArray[j + 1].Trim();
                                        break;
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
                if ((cmd == null) || !cmd.bolCancel)
                {
                    request.Abort();
                    return null;
                }
                requestStream = response.GetResponseStream();
                MemoryStream stream2 = new MemoryStream(0x400);
                byte[] buffer2 = new byte[0x400];
                while ((cmd == null) || !cmd.bolCancel)
                {
                    int count = requestStream.Read(buffer2, 0, 0x400);
                    if (count == 0)
                    {
                        break;
                    }
                    stream2.Write(buffer2, 0, count);
                }
                requestStream.Close();
                response.Close();
                request.Abort();
                byte[] buffer3 = stream2.ToArray();
                stream2.Close();
                if (buffer3 != null)
                {
                    return buffer3;
                }
            }
            return null;
        }

        IDbTransaction IDbConnection.BeginTransaction()
        {
            return null;
        }

        public override string ToString()
        {
            return ("XMLHttpConnection:" + this.ConnectionString);
        }

        public string ConnectionString
        {
            get
            {
                return this.myConnectionString.ConnectionString;
            }
            set
            {
                this.myConnectionString.ConnectionString = value;
            }
        }

        public int ConnectionTimeout
        {
            get
            {
                return this.intConnectionTimeout;
            }
        }

        public string Database
        {
            get
            {
                return this.strDataBase;
            }
        }

        public string HttpMethod
        {
            get
            {
                return this.strHttpMethod;
            }
            set
            {
                this.strHttpMethod = value;
            }
        }

        public string IECookies
        {
            get
            {
                return this.strIECookies;
            }
            set
            {
                this.strIECookies = value;
            }
        }

        public string Password
        {
            get
            {
                return this.myConnectionString.Password;
            }
            set
            {
                this.myConnectionString.Password = value;
            }
        }

        public Encoding ReserveEncod
        {
            get
            {
                return this.myReserveEncod;
            }
        }

        public int RetryNum
        {
            get
            {
                return ((this.intRetryNum > 0) ? this.intRetryNum : 1);
            }
            set
            {
                this.intRetryNum = value;
            }
        }

        public Encoding SendEncod
        {
            get
            {
                return this.mySendEncod;
            }
        }

        public string ServerPageURL
        {
            get
            {
                return this.myConnectionString.ServerPageURL;
            }
            set
            {
                this.myConnectionString.ServerPageURL = value;
            }
        }

        public ConnectionState State
        {
            get
            {
                return this.intState;
            }
        }

        public string UserName
        {
            get
            {
                return this.myConnectionString.UserName;
            }
            set
            {
                this.myConnectionString.UserName = value;
            }
        }

        public bool WinInetAPI
        {
            get
            {
                return this.bolWinInetAPI;
            }
            set
            {
                this.bolWinInetAPI = value;
            }
        }

        public class XMLHttpConnectionString
        {
            public string Password;
            public string ServerPageURL;
            public string UserName;

            public XMLHttpConnectionString()
            {
            }

            public XMLHttpConnectionString(string vConnString)
            {
                this.ConnectionString = vConnString;
            }

            public XMLHttpConnectionString(string vURL, string vUserName, string vPwd)
            {
                this.ServerPageURL = vURL;
                this.UserName = vUserName;
                this.Password = vPwd;
            }

            public string ConnectionString
            {
                get
                {
                    return (this.ServerPageURL + "@" + this.UserName + "|" + this.Password);
                }
                set
                {
                    this.ServerPageURL = StringCommon.SubStringBefore(value, "@");
                    value = StringCommon.SubStringAfter(value, "@");
                    if (StringCommon.HasContent(value))
                    {
                        this.UserName = StringCommon.SubStringBefore(value, "|");
                        this.Password = StringCommon.SubStringAfter(value, "|");
                    }
                    else
                    {
                        this.UserName = "";
                        this.Password = "";
                    }
                }
            }
        }
    }
}

